package arithmetic.Singleton;

import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author jiangfeng 2019/7/13 13:43
 */
public class TestSingleton {

    @Test
    public void testSingletonMultriThread(){

        for (int i = 0; i <10; i++) {
            new Thread(()->{
                Singleton1 instance = Singleton1.getInstance();
            }).start();
        }
    }

    /**
     * 测试内部类方式实现
     */
    @Test
    public void testSingletonMultriThread2(){

        ConcurrentHashMap map=new ConcurrentHashMap();

        for (int i = 0; i <10; i++) {
            new Thread(()->{
                Singleton2 instance = Singleton2.getInstance();
                map.put(Thread.currentThread().getName(),instance);
            },Integer.toString(i)).start();
        }
        while (map.size()<10){};
        for (int i = 0; i < 9; i++) {
            System.out.println(map.get(i)==map.get(i+1));
        }

    }

    /**
     * 反例
     */
    @Test
    public void testSingletonMultriThread1(){
        for (int i = 0; i <10; i++) {
            new Thread(()->{
                Singleton1 instance = Singleton1.getInstance2();
            }).start();
        }
    }

    ///////////////////////////////////////////////////////////////////
    @Test
    public void testSingletonInnerSerializable() throws Exception {
        Object instance = Singleton2.getInstance();
        Object instance2 = Singleton2.getInstance();
        System.out.println(instance==instance2);
        String filePath="src\\main\\java\\arithmetic\\Singleton\\object.inner";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
        objectOutputStream.writeObject(instance);
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
        Object o = objectInputStream.readObject();

        System.out.println(instance==o);

    }



    /**
     * 测试枚举序列化
     * 结果
     * true
     * false
     * 错误的演示
     *
     * @throws Exception
     */
    @Test
    public void testSingletonSerializable() throws Exception {
        Object instance = Singleton3.JEDIS_POOL.getInstance();
        Object instance2 = Singleton3.JEDIS_POOL.getInstance();

        String filePath="src\\main\\java\\arithmetic\\Singleton\\object.tx";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
        objectOutputStream.writeObject(instance);
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
        Object o = objectInputStream.readObject();

        System.out.println(instance==instance2);
        System.out.println(instance==o);

    }

    /**
     * 序列化 枚举没问题，序列化实体有问题
     * @throws Exception
     */
    @Test
    public void testSingletonSerializabl2() throws Exception {
        Object instance = Singleton3.JEDIS_POOL.getInstance();

        Singleton3 anEnum = Singleton3.JEDIS_POOL;

        String filePath="src\\main\\java\\arithmetic\\Singleton\\object.bin";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
        objectOutputStream.writeObject(anEnum);
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
        Singleton3 o = (Singleton3)objectInputStream.readObject();

        System.out.println(instance==o.getInstance());

    }
}
